1. Field of Invention
The present invention relates generally to object-based systems. More particularly, the present invention relates to methods and apparatuses for deferring the throwing of exceptions in an object-based system.
2. Description of the Relevant Art
In distributed object systems, client objects may invoke server objects. A client is typically an entity that requests that an operation be performed on an object, e.g., a server object or servant. Requests are often passed from a client to a servant through an object request broker (ORB) implementation, as defined under the Common Object Request Broker Architecture (CORBA) specification from the OMG, Revision 2.0, dated July 1995, and updated July 1996, which is incorporated herein by reference in its entirety.
Within the CORBA specification, an object model, ie., a CORBA object model, is defined over a programming language in which objects, or servants, which are implemented by servers, have references which may be exported to clients. The programming language over which the object model is defined may include, but is not limited to being, a programming language such as C++ or Java.TM., which was developed by Sun Microsystems, Inc. of Palo Alto, Calif. As will be appreciated by those skilled in the art, a particular program may serve as both a client and a server.
The CORBA object model defines an Interface Definition Language (IDL) which enables interfaces to be defined for object references that are associated with servants. Once proper interfaces are defined for object references, an IDL compiler is then typically used to translate IDL definitions of the interfaces into programming language definitions. By way of example, in the C++ programming language, the programming language definition can be a C++ class. Alternatively, in a Java.TM. environment, the programming language definition can be a Java.TM. interface.
After a programming language definition is generated by the IDL compiler, the programming language definition can be used to implement the servant associated with the programming language definition. The programming language definition may also be used to connect the servant with an appropriate object request broker (ORB) implementation, as will be appreciated by those skilled in the art.
The CORBA object model generally supports non-local invocations on servants. A client from a process different than the servant, which is in a server process, may invoke on an object reference associated with the servant. The client ORB implementation typically marshals, e.g., "packs," an invocation request and dispatches, or otherwise transfers, the invocation request to the server process. In general, an interprocess communication primitive, which complies with a protocol defined by the client and the server, is used to transfer invocation requests between the client and the server.
Once a server process receives an invocation request from the client process, the server process unmarshals, e.g., "unpacks," the invocation request, and identifies the servant within the server process which is suitable for servicing the invocation request. When the appropriate servant is located, the invocation is forwarded from the client process to the servant. As will be appreciated by those skilled in the art, the invocation request is generally forwarded with parameters which are specified by the client.
An invocation is performed on the servant in response to the invocation request from the client. After the invocation on the servant is completed, the server ORB implementation typically accumulates any results, e.g., output values, generated by the invocation, and transfers the results back to the client. The server process marshals the results for transport to the client, which, when the results are received, unmarshals the results.
Within an object-based system such as a distributed object system, exceptions may arise when objects are invoked. Exceptions can generally arise for a variety of different reasons. By way of example, exceptions often indicate that an exceptional condition, or an error, has occurred. Exceptions are typically raised either by the servant that is "servicing," or otherwise fulfilling, the request of a client, or by an ORB implementation. When an exception is raised, the exception is passed back to the client. In general, passing, or throwing, an exception, to a client serves the purpose of informing the client that an exceptional condition or error has occurred.
In some environments, such as a C++ environment, an exception is typically an exception object that resides on a call-stack for holding exceptions. The lifetime of such an exception object is generally limited by the programming language scoping of the exception handing clause in an associated skeleton structure, as will be appreciated by those skilled in the art. A skeleton, which is generated by an IDL compiler, serves as a link between an ORB implementation and a servant which is performing invocations or, more specifically, non-local invocations. While a skeleton may generally perform a variety of different tasks, the skeleton is often responsible for informing an ORB about the parameters associated with an invocation, and for invoking the servant for an object reference.
Within a C++ environment, an exception object must often exist beyond the scope of an exception handling object. Many exceptions are temporarily stored and thrown later at an appropriate time. An exception is often not immediately thrown when it arises. Rather, an exception raised by a servant, for example, may be stored and thrown to a client at a later time, as for example after "mandatory" code is executed. To delay the throwing of an exception, a copy of the exception is generally made. The C++ run-time environment allocates a copy of the exception, e.g., a dynamic copy, which is stored and eventually thrown when appropriate. In order to throw the exception, the type of exception that is being thrown must generally be known.
Code associated with making a copy of an exception, keeping track of the exception in terms of what type of exception it is, and enabling the copied exception to be thrown, is often significant. By way of example, such code often includes sections which are essentially duplicates from other sections. Hence, the overall process of throwing exceptions may be inefficient, as duplicate code must often be processed, and exception types must often be tracked. By way of example, inlining duplicate code may lead to excessive code bloat.
In addition, when copies of exceptions are made, if the copies are not released, the copies may cause memory leakage to occur. As will be appreciated by those skilled in the art, memory leakage generally occurs when memory is dynamically allocated, but is not being freed. To prevent memory leakage, memory may be periodically released. However, when memory is periodically released, a copy of an exception may be released before it has been used, i.e., thrown. Therefore, what is desired is an efficient method and apparatus for throwing exceptions in an object-based system.